package com.om.Module.openeuler;

import com.om.common.CommonObject;
import cz.mallat.uasparser.OnlineUpdater;
import cz.mallat.uasparser.UASparser;
import cz.mallat.uasparser.UserAgentInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.function.Function;
import org.codehaus.jackson.JsonNode;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;

/**
 * @author zhxia
 * @date 2020/11/3 12:51
 */
public class logstash_repo_openeuler_org extends CommonObject {

    /**
     * 功能描述:将数据组装成esapi需要的格式
     *
     * @param jsonDataObject:{"log": {
     *                               "time": "2020-09-17T12:22:34+00:00",
     *                               "proxy_remote_addr": "-",
     *                               "remote_addr": "100.125.67.202",
     *                               "x-forward-for": "100.125.67.202",
     *                               "request_id": "58e29f9860616b3ef52504bf3a15c617",
     *                               "remote_user": "-",
     *                               "bytes_sent": 659,
     *                               "request_time": 0.001,
     *                               "status": 401,
     *                               "vhost": "test.tryme.openlookeng.io",
     *                               "request_proto": "HTTP/2.0",
     *                               "path": "/lk-bn7e6esv-e1qhi/api/query/history",
     *                               "request_query": "-",
     *                               "request_length": 44,
     *                               "duration": 0.001,
     *                               "method": "GET",
     *                               "http_referrer": "https://test.tryme.openlookeng.io/lk-bn7e6esv-e1qhi/ui/",
     *                               "http_user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4181.9 Safari/537.36",
     *                               "geoip2_city_country_name": "-",
     *                               "geoip2_city": "-",
     *                               "geoip2_latitude": "-",
     *                               "geoip2_longitude": "-"
     *                               *        }
     *                               }
     * @param id:数据id
     * @return: java.util.HashMap
     * @Date: 2020/12/1 14:15
     */
    @Override
    public HashMap assemblydata(Object jsonDataObject, String id) throws KeyManagementException, NoSuchAlgorithmException, IOException {
        JsonNode jsonData = ((JsonNode) jsonDataObject);
        String time = jsonData.get("time").getTextValue();
        String ip = jsonData.get("proxy_remote_addr").getTextValue();
        //如果proxy_remote_addr没有数据则取remote_add的ip
        if (StringUtils.isBlank(ip) || "-".equals(ip)) {
            ip = jsonData.get("remote_addr").getTextValue();
        }
        //加上userAgent解析
        String userAgent = jsonData.get("http_user_agent").getTextValue();
        String[] userAgentParse = parseUserAgent(userAgent);
        //将ip放到es中解析地域信息。
        HashMap locationByIP = getLocationByIP(ip, this.esIndexName, id);
        String path = jsonData.get("path").getTextValue();
        String hostname = jsonData.get("vhost").getTextValue();
        //vhost是“www.”开头的舍弃掉“www.”
        hostname = (!StringUtils.isBlank(hostname) && hostname.startsWith("www.")) ? hostname.substring(4) : hostname;
        String locationIp = jsonData.get("remote_addr").getTextValue();
        String link = jsonData.get("request_query").getTextValue();
        HashMap<Object, Object> result = new HashMap<>();
        result.put("path", path);
        if (ismatch(path)) {
            result.put("is_internal_path", 1);
        }
        result.put("bytes_sent", jsonData.get("bytes_sent").getBigIntegerValue());
        result.put("hostname", hostname);
        result.put("updated_at", time);
        result.put("ip", ip);
        result.put("link", link);
        result.put("created_at", time);
        result.put("location_ip", locationIp);
        result.put("os", userAgentParse[0]);
        result.put("equipment", userAgentParse[1]);
        result.put("browser", userAgentParse[2]);
        result.put("location", locationByIP.get("location"));
        result.put("country", locationByIP.get("country_iso_code"));
        result.put("city", locationByIP.get("city_name"));
        result.put("region_name", locationByIP.get("region_name"));
        result.put("continent_name", locationByIP.get("continent_name"));
        result.put("region_iso_code", locationByIP.get("region_iso_code"));
        if (path.contains(".iso")) {
            result.put("is_iso_download", 1);
        } else if (path.contains(".rpm")) {
            result.put("is_rpm_download", 1);
        }
        return result;
    }

    /**
     * 功能描述:将数据组装成esapi需要的格式
     *
     * @param client:                httpclient 工具
     * @param jsonDataObject:{"log": {
     *                               * 		"time": "2020-09-17T12:22:34+00:00",
     *                               * 		"proxy_remote_addr": "-",
     *                               * 		"remote_addr": "100.125.67.202",
     *                               * 		"x-forward-for": "100.125.67.202",
     *                               * 		"request_id": "58e29f9860616b3ef52504bf3a15c617",
     *                               * 		"remote_user": "-",
     *                               * 		"bytes_sent": 659,
     *                               * 		"request_time": 0.001,
     *                               * 		"status": 401,
     *                               * 		"vhost": "test.tryme.openlookeng.io",
     *                               * 		"request_proto": "HTTP/2.0",
     *                               * 		"path": "/lk-bn7e6esv-e1qhi/api/query/history",
     *                               * 		"request_query": "-",
     *                               * 		"request_length": 44,
     *                               * 		"duration": 0.001,
     *                               * 		"method": "GET",
     *                               * 		"http_referrer": "https://test.tryme.openlookeng.io/lk-bn7e6esv-e1qhi/ui/",
     *                               * 		"http_user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4181.9 Safari/537.36",
     *                               * 		"geoip2_city_country_name": "-",
     *                               * 		"geoip2_city": "-",
     *                               * 		"geoip2_latitude": "-",
     *                               * 		"geoip2_longitude": "-"
     *                               *      *        }
     *                               * }
     * @param id:                    数据id
     * @return: java.util.HashMap
     * @Date: 2020/12/1 14:26
     */
    @Override
    public HashMap assemblydataNew(CloseableHttpClient client, Object jsonDataObject, String id) throws KeyManagementException, NoSuchAlgorithmException, IOException {
        JsonNode jsonData = ((JsonNode) jsonDataObject);
        String t = jsonData.get("time").getTextValue();
        String ip = (jsonData.get("proxy_remote_addr") == null) ? null : jsonData.get("proxy_remote_addr").getTextValue();
        //如果proxy_remote_addr没有数据则取remote_add的ip
        if (StringUtils.isBlank(ip) || "-".equals(ip)) {
            ip = jsonData.get("remote_addr").getTextValue();
        }

        //加上userAgent解析
        String userAgent = jsonData.get("http_user_agent").getTextValue();
        String[] userAgentParse = parseUserAgent(userAgent);

        HashMap locationByIP = getLocationByIPNew(client, ip, this.esIndexName, id);
        String path = jsonData.get("path").getTextValue();
        String hostname = jsonData.get("vhost").getTextValue();
        //vhost是“www.”开头的舍弃掉“www.”
        hostname = (!StringUtils.isBlank(hostname) && hostname.startsWith("www.")) ? hostname.substring(4) : hostname;

        String locationIp = jsonData.get("remote_addr").getTextValue();
        String link = jsonData.get("request_query").getTextValue();
        HashMap<Object, Object> result = new HashMap<>();
        if (ismatch(path)) {
            result.put("is_internal_path", 1);
        }
        if ("download.openlookeng.io".equals(hostname) || "repo.openeuler.org".equals(hostname)) {
            String packageVersion = downloadPackageVersion(path, 1);
            if (packageVersion != null) result.put("package_version", packageVersion);
        }
        if ("download.mindspore.cn".equals(hostname)) {
            String packageVersion = downloadPackageVersion(path, 2);
            if (packageVersion != null) result.put("package_version", packageVersion);
        }
        result.put("path", path);
        result.put("bytes_sent", jsonData.get("bytes_sent").getBigIntegerValue());
        result.put("hostname", hostname);
        result.put("updated_at", t);
        result.put("ip", ip);
        result.put("link", link);
        result.put("created_at", t);
        result.put("location_ip", locationIp);
        result.put("os", userAgentParse[0]);
        result.put("equipment", userAgentParse[1]);
        result.put("browser", userAgentParse[2]);
        result.put("location", locationByIP.get("location"));
        result.put("country", locationByIP.get("country_iso_code"));
        result.put("city", locationByIP.get("city_name"));
        result.put("region_name", locationByIP.get("region_name"));
        result.put("continent_name", locationByIP.get("continent_name"));
        result.put("region_iso_code", locationByIP.get("region_iso_code"));
        if (path.endsWith(".iso")) {
            result.put("is_iso_download", 1);
        } else if (path.endsWith(".rpm")) {
            result.put("is_rpm_download", 1);
        }
        return result;
    }


    /**
     * 功能描述:过滤数据
     *
     * @param srcRdd:原始rdd数据
     * @param vhosts:对应rdd中的vhost，如果以all为第一个元素，则跑这个rdd中的所有数据
     * @Date: 2020/12/1 14:29
     */
    @Override
    public JavaRDD dealData(JavaRDD srcRdd, String[] vhosts) {
        JavaRDD<JsonNode> records = srcRdd.map((Function<String, JsonNode>) v1 -> CommonObject.objectMapper.readTree(v1));
        JavaRDD<JsonNode> filterDatas = records.filter((Function<JsonNode, Boolean>) v1 -> {
            String s = v1.get("_source").get("log").asText();
            JsonNode vhost;
            try {
                JsonNode lognode = CommonObject.objectMapper.readTree(s);
                vhost = lognode.get("vhost");
                String path = lognode.get("path").getTextValue();
                if ((StringUtils.isBlank(path) || path.endsWith("/") || path.equals("-"))) {
                    return false;
                }
            } catch (Exception e) {
                return false;
            }
            if (vhost == null || "-".equals(vhost.getTextValue()) || StringUtils.isBlank(vhost.getTextValue())) {
                return false;
            }
            //vhost配置等于all，跑所有数据
            if ("all".equals(vhosts[0])) {
                return true;
            }
            //只跑配置的vhost
            return Arrays.asList(vhosts).contains(vhost.getTextValue());

        });
        return filterDatas;
    }

    /**
     * 功能描述:解析请求浏览器信息
     *
     * @param userAgent:
     * @return: java.lang.String[]
     * @Date: 2020/12/1 14:33
     */
    @Override
    public String[] parseUserAgent(String userAgent) {
        String[] strs = {"unknown", "unknown", "unknown"};
        try {
            UASparser uasParser = new UASparser(OnlineUpdater.getVendoredInputStream());
            UserAgentInfo userAgentInfo = uasParser.parse(userAgent); //解析userAgent
            String os = userAgentInfo.getOsName(); //操作系统
            strs[0] = (os.equals("Windows") && userAgent.contains("Windows NT 10.0")) ? "Windows 10" : os;
            strs[1] = userAgentInfo.getDeviceType(); //设备
            strs[2] = userAgentInfo.getUaName(); //浏览器
            return strs;
        } catch (IOException e) {
            e.printStackTrace();
            return strs;
        }
    }

    private String downloadPackageVersion(String path, int versionIndex) {
        String res = null;
        switch (versionIndex) {
            case 1:
                if (path != null && path.matches("^/.*/.*")) {
                    String[] split = path.split("/");
                    res = split[versionIndex];
                }
                break;
            case 2:
                if (path != null && path.matches("^/.*/.*/.*")) {
                    String[] split = path.split("/");
                    res = split[versionIndex];
                }
                break;
            default:
        }
        return res;

    }

}
